package top.easyblog.core.scheduling;

import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import top.easyblog.core.annotation.CostTimeTracker;
import top.easyblog.core.annotation.DLock;
import top.easyblog.core.annotation.RequestId;
import top.easyblog.core.service.CompressCodeService;
import top.easyblog.core.support.lock.DistributedLock;
import top.easyblog.core.support.lock.RedisDistributeLockFactory;
import top.easyblog.core.support.queue.CompressionCodeBlockingQueue;
import top.easyblog.core.util.ConcurrentUtils;

import static top.easyblog.common.constant.RedisDistributeKeyConstants.COMPRESSION_CODE_QUEUE_FLUSH_KEY;

/**
 * 定时补充压缩码到Redis队列中
 *
 * @author: frank.huang
 * @date: 2023-12-30 22:29
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class CompressionCodeQueueFlushTask {

    private final RedisDistributeLockFactory redisDistributeLockFactory;

    private final CompressCodeService compressCodeService;


    // 定时任务，每隔5秒执行一次。扫描数量，如果数量不足 500w，就生成数据。
    // 按照 QPS 2w/s 算，可以支撑 4 分钟的使用量。 每隔 10s 扫描一下，每次补充 100w 数据，基本保证补充线程与获取线程不互相影响。
    @RequestId
    @Scheduled(cron = "*/10 * * * * ?")
    public void process() {
        ConcurrentUtils.executeTaskInNonBlockModel(Lists.newArrayList(this::doTask), null);
    }


    @CostTimeTracker
    public void doTask() {
        DistributedLock lock = redisDistributeLockFactory.getNonWaitingDistributedLock(COMPRESSION_CODE_QUEUE_FLUSH_KEY);
        boolean tryLock = false;
        try {
            tryLock = lock.lock();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        if (tryLock) {
            try {
                CompressionCodeBlockingQueue queue = compressCodeService.getQueue();
                queue.batchOffer();
            } catch (Exception e) {
                e.printStackTrace();
                log.warn("执行定时补充压缩码到Redis队列中任务失败：" + e);
            } finally {
                lock.unlock();
            }
        }
    }

}
